package fun.yyds.controller.es;

import io.swagger.v3.oas.annotations.tags.Tag;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

@RestController
@Tag(name = "6.ESBK")
@RequestMapping("/esbk")
public class EsBkController {
    @Resource
    private RestHighLevelClient client;

    @Value("${es.backup.path}")
    private String backupPath;

    @Value("${es.backup.days}")
    private int days;

    @Value("${es.backup.time-format}")
    private String timeFormat;

    // 自动备份近30天数据
    @Scheduled(cron = "0 0 0 */30 * ?") // 每30天执行一次
    public void autoBackupRecentData() {
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(days);
        backupData("recent", startDate, endDate);
    }

    // 手动备份全量数据
    @PostMapping("/backup/full")
    public ResponseEntity<String> manualBackupFull() {
        backupData("full", null, null);
        return ResponseEntity.ok("Full backup started");
    }

    private void backupData(String backupType, LocalDate startDate, LocalDate endDate) {
        try {
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern(timeFormat));
            String backupFileName = String.format("efk_log_%s_%s.json", backupType, timestamp);
            Path backupFilePath = Paths.get(backupPath, backupFileName);

            // 创建备份目录
            Files.createDirectories(backupFilePath.getParent());

            // 执行查询并写入文件
            try (BufferedWriter writer = Files.newBufferedWriter(backupFilePath)) {
                SearchRequest searchRequest = buildSearchRequest(startDate, endDate);
                SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

                for (SearchHit hit : response.getHits().getHits()) {
                    writer.write(hit.getSourceAsString());
                    writer.newLine();
                }
            }

            log.println("Backup completed: " + backupFilePath);
//            cleanupOldBackups();

        } catch (IOException e) {
            log.println("Backup failed" + e);
            throw new RuntimeException("Backup operation failed", e);
        }
    }

    private SearchRequest buildSearchRequest(LocalDate startDate, LocalDate endDate) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        if (startDate != null && endDate != null) {
            queryBuilder.must(QueryBuilders.rangeQuery("createTime")
                    .gte(startDate.atStartOfDay())
                    .lte(endDate.atTime(23, 59, 59)));
        }

        sourceBuilder.query(queryBuilder);
        return new SearchRequest("efk_log*").source(sourceBuilder);
    }

//    private void cleanupOldBackups() {
//        try (Stream<Path> paths = Files.list(Paths.get(backupPath))) {
//            paths.filter(Files::isRegularFile)
//                    .filter(p -> p.getFileName().toString().startsWith("efk_log_"))
//                    .filter(p -> {
//                        String datePart = p.getFileName().toString().split("_")[2].replace(".json", "");
//                        return LocalDate.parse(datePart, DateTimeFormatter.ofPattern(timeFormat))
//                                .isBefore(LocalDate.now().minusDays(retentionDays));
//                    })
//                    .forEach(p -> {
//                        try {
//                            Files.delete(p);
//                            log.println("Deleted old backup: {}" + p);
//                        } catch (IOException e) {
//                            log.println("Failed to delete old backup: {}" + p + e);
//                        }
//                    });
//        } catch (IOException e) {
//            log.println("Error cleaning up old backups" + e);
//        }
//    }
}
